package coil3.map
import coil3.Uri
import coil3.request.Options
import coil3.toUri
import kotlinx.cinterop.ByteVar
import kotlinx.cinterop.CPointerVar
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.alloc
import kotlinx.cinterop.free
import kotlinx.cinterop.nativeHeap
import kotlinx.cinterop.nativeHeap.free
import kotlinx.cinterop.ptr
import kotlinx.cinterop.toKString
import kotlinx.cinterop.value
import platform.framework.ERR_OK
import platform.framework.FileManagement_ErrCode
import platform.framework.OH_FileUri_GetPathFromUri
import platform.framework.OH_FileUri_IsValidUri
import platform.posix.free


internal actual class NSURLMapper : coil3.map.Mapper<Any, coil3.Uri> {

    actual constructor()

    @OptIn(ExperimentalForeignApi::class)
    internal fun getUriString(data: String): String {
        val buffer = nativeHeap.alloc<CPointerVar<ByteVar>>().apply {
            value = null
        }
        try {
            val path: String = data.toString();
            val ret: FileManagement_ErrCode =
                OH_FileUri_GetPathFromUri(path, path.length.toUInt(), buffer.ptr);
            if (ret != ERR_OK) {
                println("OH_FileUri_GetPathFromUri failed! ret = $ret");
                return "";
            }
            val result:String = buffer.value?.toKString() ?: ""
            return result;
        } finally {
                buffer.value?.let {
                free(it)
            }
            nativeHeap.free(buffer)
            }
    }

    internal fun isPlatformUri(data: String) : Boolean {
        val path:String = data.toString();
        @OptIn(ExperimentalForeignApi::class)
        val ret:Boolean = OH_FileUri_IsValidUri(path, path.length.toUInt());
        return ret;
    }

    actual override fun map(data: Any, options: Options): Uri? {
        if (!isPlatformUri(data.toString())) return null
        return getUriString(data.toString()).toUri()
    }
}
